//
// Created by 李锋 on 2024/4/12.
//

#include "usart_msg.h"

UsartFrameStruct 	send_frame_struct;      //<(发送)通信帧结构体
UsartFrameStruct   rec_frame_struct;     //<(接收)通信帧结构体

/**
  * @brief   初始化通信帧结构体,使用前必须调用
  * @param   无输入参数
  * @retval  无返回
  **/
void usart_frame_init(void)
{
    /*参数结构体初始化*/

    send_frame_struct.head=rec_frame_struct.head=FRAME_HEADER;//帧头固定是0XAA
    send_frame_struct.target_addr=rec_frame_struct.target_addr=HOST_ADDR;
    send_frame_struct.function_id=0XFF;//<协议中没有定义的功能ID,这样初始化目的是为了启动瞬间不做任何动作


    memset(send_frame_struct.data,0,40);//<缓存默认全部置0
    memset(rec_frame_struct.data,0,40);
}

/**
  * @brief   复位通信帧结构体，ano_frame_init()必须要运行过一次
  * @param   通信帧结构体对象
  * @retval  无返回
  **/
void usart_frame_reset(UsartFrameStruct* frame)
{
    frame->function_id=0XFF;
    frame->data_len=0;
    memset(frame->data,0,40);
    frame->add_check=0;
    frame->sum_check=0;
}



/**
  * @brief   通信帧校验计算
  * @param   通信帧结构体对象
  * @retval  无返回值
  **/
void usart_check_calculate(UsartFrameStruct* frame)
{
    frame->sum_check=0;
    frame->add_check=0;

    //除去和校验，附加校验及数据部分，有4个部分4个字节，长度固定
    for(uint32_t i=0;i<4;i++)
    {
        frame->sum_check+= *(uint8_t*)(&frame->head+i);
        frame->add_check+=frame->sum_check;
    }
    //获取数据长度部位,把数据部分全加上
    for(uint32_t i=0;i<frame->data_len;i++)
    {
        frame->sum_check+=*((uint8_t*)(frame->data)+i);
        frame->add_check+=frame->sum_check;
    }
}
/**
  * @brief   通信帧校验检查(接收上位机通信帧时用)
  * @param   通信帧结构体对象
 * @retval   1：校验成功 0:校验失败
  **/
uint8_t usart_check(UsartFrameStruct* frame)
{
    uint8_t sum_check=0;
    uint8_t add_check=0;

    for(uint32_t i=0;i<4;i++)
    {
        sum_check+= *(uint8_t*)(&frame->head+i);
        add_check+=sum_check;
    }
    for(uint32_t i=0;i<frame->data_len;i++)
    {
        sum_check+=*((uint8_t*)(frame->data)+i);
        add_check+=sum_check;
    }
    //如果计算与获取的相等，校验成功
    if((sum_check==frame->sum_check)&&(add_check==frame->add_check))
        return 1;
    else
        return 0;
}

/**
  * @brief   通信帧结构体转化为线性数组
  * @param   要转换的通信帧，缓存数组
  * @retval
  **/
void frame_turn_to_array(UsartFrameStruct* frame,uint8_t*str)
{
    memcpy(str,(uint8_t*)frame,4);
    memcpy(str+4,(uint8_t*)frame->data,frame->data_len);
    memcpy(str+4+frame->data_len,(uint8_t*)(&frame->sum_check),2);
}
